package com.ls.lserp.modules.sys.service;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.ls.lserp.modules.sys.entity.QualityCount;
import org.apache.shiro.session.Session;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.ls.lserp.common.config.Global;
import com.ls.lserp.common.persistence.Page;
import com.ls.lserp.common.security.Digests;
import com.ls.lserp.common.security.shiro.session.SessionDAO;
import com.ls.lserp.common.service.BaseService;
import com.ls.lserp.common.service.ServiceException;
import com.ls.lserp.common.utils.CacheUtils;
import com.ls.lserp.common.utils.Encodes;
import com.ls.lserp.common.utils.ResourcesUtil;
import com.ls.lserp.common.utils.StringUtils;
import com.ls.lserp.common.web.Servlets;
import com.ls.lserp.dbaccess.Entity.MailMessage;
import com.ls.lserp.dbaccess.Entity.MaterialBreak;
import com.ls.lserp.dbaccess.Entity.MaterialRemainEntity;
import com.ls.lserp.dbaccess.Entity.OrderEntity;
import com.ls.lserp.dbaccess.Entity.ProductionItemEntity;
import com.ls.lserp.modules.order.dao.CustomizationUnitDao;
import com.ls.lserp.modules.order.dao.OrderDao;
import com.ls.lserp.modules.order.entity.Order;
import com.ls.lserp.modules.order.entity.StyleOptionEntity;
import com.ls.lserp.modules.produce.dao.CustomizationQualityDao;
import com.ls.lserp.modules.produce.dao.ProduceWorkticketDao;
import com.ls.lserp.modules.produce.entity.ProduceWorkticketEntity;
import com.ls.lserp.modules.sys.dao.MenuDao;
import com.ls.lserp.modules.sys.dao.RoleDao;
import com.ls.lserp.modules.sys.dao.ShopDao;
import com.ls.lserp.modules.sys.dao.UserDao;
import com.ls.lserp.modules.sys.entity.Menu;
import com.ls.lserp.modules.sys.entity.OrderQualityCount;
import com.ls.lserp.modules.sys.entity.Role;
import com.ls.lserp.modules.sys.entity.User;
import com.ls.lserp.modules.sys.security.SystemAuthorizingRealm;
import com.ls.lserp.modules.sys.utils.LogUtils;
import com.ls.lserp.modules.sys.utils.UserUtils;
import com.mysql.fabric.xmlrpc.base.Array;

/**
 * 系统管理，安全相关实体的管理类,包括用户、角色、菜单.
 * @author LiuPeng
 * @version 2016-10-18
 */
@Service
@Transactional(readOnly = true)
public class SystemService extends BaseService implements InitializingBean {
	
	public static final String HASH_ALGORITHM = "SHA-1";
	public static final int HASH_INTERATIONS = 1024;
	public static final int SALT_SIZE = 8;
	
	@Autowired
	private ShopDao shopDao;
	@Autowired
	private UserDao userDao;
	@Autowired
	private RoleDao roleDao;
	@Autowired
	private MenuDao menuDao;
	@Autowired
	private SessionDAO sessionDao;
	@Autowired
    private ProduceWorkticketDao produceWorkticketDao;
	@Autowired
	private SystemAuthorizingRealm systemRealm;
	@Autowired
	private CustomizationUnitDao customizationUnitDao;
	@Autowired
	private CustomizationQualityDao customizationQualityDao;
	@Autowired
	private OrderDao orderDao;
	
	public SessionDAO getSessionDao() {
		return sessionDao;
	}

	/**
	 * 获取用户
	 * @param id
	 * @return
	 */
	public User getUser(Long id) {
		return UserUtils.get(id);
	}

	/**
	 * 根据登录名获取用户
	 * @param loginName
	 * @return
	 */
	public User getUserByLoginName(String loginName) {
		return UserUtils.getByLoginName(loginName);
	}
	
	/**
	  * @Title: checkEmailName
	  * @Description: 邮箱唯一验证
	  * @param @param user
	  * @param @return
	  * @return User 
	  * @throws
	  */
	
	public User checkEmailName(User user){
		return userDao.checkEmailName(user);
	}
	/**
	  * @Title: findUser
	  * @Description: 
	  * @param @param page
	  * @param @param user
	  * @param @return
	  * @return Page<User> 
	  * @throws
	  */
	
	public Page<User> findUser(Page<User> page, User user) {
		// 生成数据权限过滤条件（dsf为dataScopeFilter的简写，在xml中使用 ${sqlMap.dsf}调用权限SQL）
		user.getSqlMap().put("dsf", dataScopeFilter(user.getCurrentUser(), "o", "a"));
		// 设置分页参数
		user.setPage(page);
		// 执行分页查询
		page.setList(userDao.findList(user));
		return page;
	}
	
	/**
	  * @Title: findRole
	  * @Description: 
	  * @param @param page
	  * @param @param role
	  * @param @return
	  * @return Page<Role> 
	  * @throws
	  */
	
	public Page<Role> findRole(Page<Role> page, Role role) {
       /* // 生成数据权限过滤条件（dsf为dataScopeFilter的简写，在xml中使用 ${sqlMap.dsf}调用权限SQL）
	    role.getSqlMap().put("dsf", dataScopeFilter(role.getCurrentUser(), "o", "a"));*/
        // 设置分页参数
        role.setPage(page);
        // 执行分页查询
        page.setList(roleDao.findList(role));
        return page;
    }
	
	/**
	 * 无分页查询人员列表
	 * @param user
	 * @return
	 */
	public List<User> findUser(User user){
		// 生成数据权限过滤条件（dsf为dataScopeFilter的简写，在xml中使用 ${sqlMap.dsf}调用权限SQL）
		user.getSqlMap().put("dsf", dataScopeFilter(user.getCurrentUser(), "o", "a"));
		List<User> list = userDao.findList(user);
		return list;
	}

	/**
	  * @Title: saveUser
	  * @Description: 保存用户
	  * @param @param user
	  * @return void 
	  * @throws
	  */
	@Transactional(readOnly = false)
	public void saveUser(User user) {
		if (user.getId()==null){
			user.preInsert();
			userDao.insert(user);
			Map<Object, Object> paramMap =new HashMap<Object,Object>();  
            
			// 店ID ※※※※※※※※  = 共通      ※※※※※※※※※※※
            paramMap.put("shopId", UserUtils.getUser().getShop().getId());
            
            paramMap.put("userId", user.getId());
            // 插入店铺关联信息表
            shopDao.insertShopId(paramMap);
		}else{
			// 更新用户数据
			user.preUpdate();
			userDao.update(user);
		}
		if (user.getId()!=null){
			// 更新用户与角色关联
			userDao.deleteUserRole(user);
			if (user.getRole() != null && user.getRole().getId()!=null){
				userDao.insertUserRole(user);
			}else{
				throw new ServiceException(user.getLoginName() + StringUtils.getMessage("user_noRole",null));
			}
			// 清除用户缓存
			UserUtils.clearCache(user);
		}
	}
	
	/**
	  * @Title: updatePassword
	  * @Description: 更新密码
	  * @param @param user
	  * @return void 
	  * @throws
	  */
	
	@Transactional(readOnly = false)
	public void updatePassword(User user) {
		    // 更新用户数据
			user.preUpdate();
			userDao.updatePassword(user);
			// 清除用户缓存
			UserUtils.clearCache(user);
	}
	
	/**
	  * @Title: updatePassword
	  * @Description: 更新邮箱验证
	  * @param @param user
	  * @return void 
	  * @throws
	  */
	
	@Transactional(readOnly = false)
	public void updateCheckEmailById(User user) {
			// 更新邮箱验证
			userDao.updateCheckEmailById(user);
	}
	/**
	 * 修改用户信息
	 * @param user
	 */
	@Transactional(readOnly = false)
	public void updateUserInfo(User user) {
		user.preUpdate();
		userDao.updateUserInfo(user);
		// 清除用户缓存
		UserUtils.clearCache(user);
//		// 清除权限缓存
//		systemRealm.clearAllCachedAuthorizationInfo();
	}
	/**
	 * 删除用户信息
	 * @param user
	 */
	@Transactional(readOnly = false)
	public void deleteUser(User user) {
		userDao.delete(user);
		// 清除用户缓存
		UserUtils.clearCache(user);
//		// 清除权限缓存
	}
	
	/**
	 * 修改密码
	 * @param id
	 * @param loginName
	 * @param newPassword
	 */
	@Transactional(readOnly = false)
	public void updatePasswordById(Long id, String loginName, String newPassword) {
		User user = new User(id);
		user.setPassword(entryptPassword(newPassword));
		userDao.updatePasswordById(user);
		// 清除用户缓存
		user.setLoginName(loginName);
		UserUtils.clearCache(user);
	}
	
	/**
	 * 修改用户登录信息
	 * @param user
	 */
	@Transactional(readOnly = false)
	public void updateUserLoginInfo(User user) {
		// 更新本次登录信息
		user.setLoginIp(StringUtils.getRemoteAddr(Servlets.getRequest()));
		user.setLastDate(new Date());
		userDao.updateLoginInfo(user);
	}
	
	/**
	 * 生成安全的密码，生成随机的16位salt并经过1024次 sha-1 hash
	 */
	public static String entryptPassword(String plainPassword) {
		String plain = Encodes.unescapeHtml(plainPassword);
		byte[] salt = Digests.generateSalt(SALT_SIZE);
		byte[] hashPassword = Digests.sha1(plain.getBytes(), salt, HASH_INTERATIONS);
		return Encodes.encodeHex(salt)+Encodes.encodeHex(hashPassword);
	}
	
	/**
	 * 验证密码
	 * @param plainPassword 明文密码
	 * @param password 密文密码
	 * @return 验证成功返回true
	 */
	public static boolean validatePassword(String plainPassword, String password) {
		String plain = Encodes.unescapeHtml(plainPassword);
		byte[] salt = Encodes.decodeHex(password.substring(0,16));
		byte[] hashPassword = Digests.sha1(plain.getBytes(), salt, HASH_INTERATIONS);
		return password.equals(Encodes.encodeHex(salt)+Encodes.encodeHex(hashPassword));
	}
	
	/**
	 * 获得活动会话
	 * @return
	 */
	public Collection<Session> getActiveSessions(){
		return sessionDao.getActiveSessions(false);
	}
	
	//-- Role Service --//
	
	public Role getRole(Long id) {
		return roleDao.get(id);
	}
    /**
     * 根据名称查询角色
     * @param name
     * @return
     */
	public Role getRoleByName(String name) {
		Role r = new Role();
		r.setRoleName(name);
		return roleDao.getByName(r);
	}
	
	public User getByLoginName(String name) {
		User r = new User();
		r.setLoginName(name);
		return userDao.getByLoginName(r);
	}
	/**
	 * 查询角色列表
	 * @param role
	 * @return
	 */
	public List<Role> findRole(Role role){
		return roleDao.findList(role);
	}
	/**
	 * 查询所有角色
	 * @return
	 */
	public List<Role> findAllRole(){
		return UserUtils.getRoleList();
	}
	
	/**
	  * @Title: saveRole
	  * @Description:角色设置保存 
	  * @param @param role
	  * @return void 
	  * @throws
	  */
	
	@Transactional(readOnly = false)
	public void saveRole(Role role) {
		
	    if (role.getId()==null){
			role.preInsert();
			roleDao.insert(role);
		}else{
			role.preUpdate();
			roleDao.update(role);
		}
		// 更新角色与菜单关联
		roleDao.deleteRoleMenu(role);
		if (role.getMenuList().size() > 0){
			roleDao.insertRoleMenu(role);
		}
		UserUtils.removeCache(UserUtils.CACHE_ROLE_LIST);
	}

	/**
	  * @Title: deleteRole
	  * @Description:角色设置删除 
	  * @param @param role
	  * @return void 
	  * @throws
	  */
	
	@Transactional(readOnly = false)
	public void deleteRole(Role role) {
		roleDao.delete(role);
		// 清除用户角色缓存
		UserUtils.removeCache(UserUtils.CACHE_ROLE_LIST);
	}
	
	@Transactional(readOnly = false)
	public Boolean outUserInRole(Role role, User user) {
		List<Role> roles = user.getRoleList();
		for (Role e : roles){
			if (e.getId().equals(role.getId())){
				roles.remove(e);
				saveUser(user);
				return true;
			}
		}
		return false;
	}
	
	@Transactional(readOnly = false)
	public User assignUserToRole(Role role, User user) {
		if (user == null){
			return null;
		}
		List<Long> roleIds = user.getRoleIdList();
		if (roleIds.contains(role.getId())) {
			return null;
		}
		user.getRoleList().add(role);
		saveUser(user);
		return user;
	}

	//-- Menu Service --//
	
	public Menu getMenu(Long id) {
		return menuDao.get(id);
	}

	public List<Menu> findMenu(){
		return UserUtils.getMenuList();
	}
	
	public List<Menu> findAllMenu(){
        return UserUtils.getMenuAllList();
    }
	
	@Transactional(readOnly = false)
	public void saveMenu(Menu menu) {
		
		// 获取父节点实体
		menu.setParent(this.getMenu(menu.getParent().getId()));
		
		// 获取修改前的parentIds，用于更新子节点的parentIds
		String oldParentIds = menu.getParentIds(); 
		
		// 设置新的父节点串
		menu.setParentIds(menu.getParent().getParentIds()+menu.getParent().getId()+",");

		// 保存或更新实体
		if (menu.getId()==null){
			menu.preInsert();
			menuDao.insert(menu);
		}else{
			menu.preUpdate();
			menuDao.update(menu);
		}
		
		// 更新子节点 parentIds
		Menu m = new Menu();
		m.setParentIds("%,"+menu.getId()+",%");
		List<Menu> list = menuDao.findByParentIdsLike(m);
		for (Menu e : list){
			e.setParentIds(e.getParentIds().replace(oldParentIds, menu.getParentIds()));
			menuDao.updateParentIds(e);
		}
		// 清除用户菜单缓存
		UserUtils.removeCache(UserUtils.CACHE_MENU_LIST);
//		// 清除权限缓存
//		systemRealm.clearAllCachedAuthorizationInfo();
		// 清除日志相关缓存
		CacheUtils.remove(LogUtils.CACHE_MENU_NAME_PATH_MAP);
	}

	@Transactional(readOnly = false)
	public void updateMenuSort(Menu menu) {
		menuDao.updateSort(menu);
		// 清除用户菜单缓存
		UserUtils.removeCache(UserUtils.CACHE_MENU_LIST);
//		// 清除权限缓存
//		systemRealm.clearAllCachedAuthorizationInfo();
		// 清除日志相关缓存
		CacheUtils.remove(LogUtils.CACHE_MENU_NAME_PATH_MAP);
	}

	@Transactional(readOnly = false)
	public void deleteMenu(Menu menu) {
		menuDao.delete(menu);
		// 清除用户菜单缓存
		UserUtils.removeCache(UserUtils.CACHE_MENU_LIST);
//		// 清除权限缓存
//		systemRealm.clearAllCachedAuthorizationInfo();
		// 清除日志相关缓存
		CacheUtils.remove(LogUtils.CACHE_MENU_NAME_PATH_MAP);
	}
	
	/**
	 * 获取Key加载信息
	 */
	public static boolean printKeyLoadMessage(){
		StringBuilder sb = new StringBuilder();
		sb.append("\r\n======================================================================\r\n");
		sb.append("\r\n    欢迎使用 "+Global.getConfig("productName")+"  - Powered By 碎片智能\r\n");
		sb.append("\r\n======================================================================\r\n");
		System.out.println(sb.toString());
		return true;
	}
	
    @Override
    public void afterPropertiesSet() throws Exception {
        // TODO Auto-generated method stub
        
    }
    /**
	 *  统计质检数量
	 */
	@Transactional(readOnly = false)
	public List<QualityCount> getQualityCount(Date beginDate,Date endDate) {
		/*Date now = new Date();
		SimpleDateFormat sdf=new SimpleDateFormat("MMdd");
		List <QualityCount> qualityListALL = new ArrayList<>();
		String strStartDate ="";
		String strEndDate="";
		if(beginDate!=null&&endDate!=null){
			 strStartDate = sdf.format(beginDate);
			 strEndDate = sdf.format(endDate);
		}
		String tmpDate = "";
		int resultDate = 1;
		if(!strStartDate.equals("") && !strEndDate.equals(""))
		{
			for (int j=0;resultDate >0 ;j++ ){
				tmpDate = String.valueOf(sdf.format(new Date(beginDate.getTime() -(long)j * 24 * 60 * 60 * 1000)));
				List<QualityCount> qualityList = menuDao.getQualityCount(tmpDate);
				qualityListALL.addAll(qualityList);
				resultDate = Integer.parseInt(tmpDate) - Integer.parseInt(strEndDate);
			}
		}else {
			for (int i = 0; i < 14; i++) {
				String strQualityData = String.valueOf(sdf.format(new Date(now.getTime() - (long) (13 - i) * 24 * 60 * 60 * 1000)));
				List<QualityCount> qualityList = menuDao.getQualityCount(strQualityData);
				qualityListALL.addAll(qualityList);
			}
		}*/
		List<QualityCount> qualityList = menuDao.getQualityCount(endDate,beginDate);
		return qualityList;
	}
	/**
	 * 统计订单数量
	 */
	@Transactional(readOnly = false)
	public List<OrderQualityCount> getOrderQualityCount(Date endDate,Date beginDate) {
		List<OrderQualityCount> orderAllList = new ArrayList<>();
//		Date cDate = new Date();
//		OrderQualityCount orderQualityCount = new OrderQualityCount();
//		Calendar date = Calendar.getInstance();
//		int days = ((int)(endDate.getTime()/1000)-(int)(beginDate.getTime()/1000))/3600/24;   
//		for (int i = days; i >= 0; i--) {
//			cDate = endDate;
//			date.setTime(cDate);
//			date.set(Calendar.DATE, date.get(Calendar.DATE) - i);
//			orderQualityCount = menuDao.getOrderQualityCount(date.getTime());
//			orderAllList.add(orderQualityCount);
//		}
		orderAllList = menuDao.getOrderQualityCount(beginDate,endDate);
		return orderAllList;
	}
	/**
	 * 查询邮件内容
	 */
	@Transactional(readOnly = false)
	public List<MailMessage> getMailMessage() {
		List<MailMessage> mailAllList = new ArrayList<>();
		mailAllList = menuDao.getMailMessage();
		return mailAllList;
	}
	/**
	 * 查询当前登录人的组别
	 * @return 
	 */
	@Transactional(readOnly = false)
	public int getGroupId(long userId) {
		int groupId = menuDao.getGroupId(userId);
		return groupId;
	}
	/**
	 * 查询最新生产状态
	 * @return 
	 */
	@Transactional(readOnly = false)
	public List<ProduceWorkticketEntity> getProduction(ProduceWorkticketEntity produceWorkticketEntity) {
		return produceWorkticketDao.findDetailList(produceWorkticketEntity);
	}
	
	/**
	 * 查询面料断料
	 * @return 
	 */
	@Transactional(readOnly = false)
	public List<MaterialBreak> getMaterialBreak() {
		List<MaterialBreak> materialBreakAllList = new ArrayList<>();
		materialBreakAllList = menuDao.getMaterialBreak();
		return materialBreakAllList;
	}
	
	/**
	 * 按条件检索面料断料
	 * @return 
	 */
	@Transactional(readOnly = false)
	public List<MaterialBreak> searchMaterialBreak(String contactNo,int makeFlag) {
		List<MaterialBreak> materialBreakAllList = new ArrayList<>();
		materialBreakAllList = menuDao.searchMaterialBreak(contactNo,makeFlag);
		return materialBreakAllList;
	}
	
	
	/**
	 * 更新状态
	 * @return 
	 */
	@Transactional(readOnly = false)
	public void updateStatus(String styleId , MaterialRemainEntity materialRemainEntity) throws Exception {
		//更新断料工序状态
		String[] styleIdTemp = styleId.split("-");
		if (styleIdTemp.length > 0) {
			for (int i = 0; i < styleIdTemp.length; i++) {
				menuDao.updateStatus(styleIdTemp[i],ResourcesUtil.getConfig("OPERATING_STATUS10"));
				Order order = orderDao.getOrderByStyleId(Long.parseLong(styleIdTemp[i]));
				//插入工时表数据
				ProductionItemEntity productionItemEntity = new ProductionItemEntity();
				Long productionId = customizationQualityDao.getProductionId(order.getId());
				if (productionId != null) {
					productionItemEntity.setProductionId(productionId);
					productionItemEntity.setCreateDateTime(new Date());
					productionItemEntity.setUpdateDateTime(new Date());
					productionItemEntity.setCreateUserId(UserUtils.getUser().getId());
					productionItemEntity.setUpdateUserId(UserUtils.getUser().getId());
					productionItemEntity.setOrderId(order.getId());
					productionItemEntity.setOrderNo(order.getOrderNO());
					productionItemEntity.setBarCode(order.getOrderNO().substring(order.getOrderNO().indexOf(".")+1));
					productionItemEntity.setItemId(1L);
					productionItemEntity.setProcessStatus(ResourcesUtil.getConfig("OPERATING_STATUS10"));
					productionItemEntity.setProcessNumber(new BigDecimal(1));
					orderDao.insertProItem(productionItemEntity);
				}
			}
		}
		//插入料头表数据
		if (materialRemainEntity != null && materialRemainEntity.getMaterialQuantity() != null) {
			MaterialRemainEntity materialRemainCheck = menuDao.findMaterialRemain(materialRemainEntity);
			if (materialRemainCheck != null) {
				//更新料头数量
				materialRemainEntity.preUpdate();
				menuDao.updateMaterialRemainAdd(materialRemainEntity);
			}else {
				//插入一条新数据
				materialRemainEntity.preInsert();
				menuDao.insertMaterialRemain(materialRemainEntity);
			}
		}
	}
	/**
	 * 按条件检索所有订单数据
	 * @return 
	 */
	@Transactional(readOnly = false)
	public List<MaterialBreak> searchMaterialAll(String contactNo,String materialName,int makeFlag) {
		List<MaterialBreak> materialAllList = new ArrayList<>();
		materialAllList = menuDao.searchMaterialAllList(contactNo,materialName,makeFlag);
		return materialAllList;
	}
	
	/**
	 * 按条件检索未断料的订单数据
	 * @return 
	 */
	@Transactional(readOnly = false)
	public List<MaterialBreak> searchMaterialUnbreak(String contactNo,String materialName,int makeFlag) {
		List<MaterialBreak> materialAllList = new ArrayList<>();
		materialAllList = menuDao.searchMaterialUnbreak(contactNo,materialName,makeFlag);
		return materialAllList;
	}
	/**
	 * 查询合同号
	 * @return 
	 */
	@Transactional(readOnly = false)
	public List<StyleOptionEntity> getContractCustom() {
		List<StyleOptionEntity> contractCustomList = new ArrayList<>();
		contractCustomList = customizationUnitDao.findContractInfo();
		return contractCustomList;
	}
	
}
